using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;

namespace LFromeWork
{
    public class CheckVersionManager : IDisposable
    {
        /// <summary>
        /// 版本文件 管理器
        /// </summary>
        public VersionFileManager VersionFile { get; private set; }

        /// <summary>
        /// 检查版本更新下载时候的参数
        /// </summary>
        private BaseParams m_DownloadingParams;

        public event Action CheckVersionBeginDownload;
        public event Action<BaseParams> CheckVersionDownloadUpdate;
        public event Action CheckVersionDownloadComplete;

        public Action CheckVersionComplete;


        public CheckVersionManager()
        {
            VersionFile = new VersionFileManager();
        }

        internal void Init()
        {
        }

        /// <summary>
        /// 初始化版本号
        /// </summary>
        public void InitVersionNumber(int gameId)
        {
            VersionFile.GetLocalVersionNumber(gameId);
            VersionFile.GetServerVersionNumber(gameId, GameLaunch.CheckVersion.VersionFile.LocalVersionNumber, (isError) => 
            {
                if (isError)
                {
                    GameLaunch.LogError("获取服务器版本号 错误 gameId:: " + gameId);
                }
                else 
                {
                    GameLaunch.LogError("获取服务器版本号 完成 gameId:: " + gameId); 
                    CheckVersionChange();
                }
            });
        }

        /// <summary>
        /// 检查更新
        /// </summary>
        public void CheckVersionChange()
        {
            Debug.Log(string.Format("检查更新=>CheckVersionChange(), 版本号=>{0}", VersionFile.LocalVersionNumber));
            
            if (VersionFile.LocalVersionNumber.Equals(VersionFile.CDNVersionNumber))
            {
                Debug.Log("可写区版本号和CDN版本号一致 进入预加载流程");
                CheckVersionComplete?.Invoke();
            }
            else
            {
                Debug.Log("可写区版本号和CDN版本号不一致 开始检查更新");
                GameLaunch.CheckVersion.VersionFile.InitLocalVersionFile();
                GameLaunch.CheckVersion.VersionFile.InitCDNVersionFile(() =>
                {
                    BeginCheckVersionChange();
                });
            }
        }

        /// <summary>
        /// 开始检查更新
        /// </summary>
        private void BeginCheckVersionChange()
        {
            m_DownloadingParams = BaseParams.Create();

            //需要删除的文件
            LinkedList<string> deleteList = new LinkedList<string>();

            //需要下载的文件
            LinkedList<string> needDownloadList = new LinkedList<string>();

            //找出需要删除的文件
            var enumerator = VersionFile.m_LocalAssetsVersionDic.GetEnumerator();
            while (enumerator.MoveNext())
            {
                string assetBundleName = enumerator.Current.Key;

                VersionFileEntity cdnAssetBundleInfo = null;
                if (VersionFile.m_CDNVersionDic.TryGetValue(assetBundleName, out cdnAssetBundleInfo))
                {
                    //可写区有 CDN也有
                    if (!cdnAssetBundleInfo.MD5.Equals(enumerator.Current.Value.MD5, StringComparison.CurrentCultureIgnoreCase))
                    {
                        //如果MD5不一致 加入下载链表
                        needDownloadList.AddLast(assetBundleName);
                    }
                }
                else
                {
                    //可写区有 CDN上没有 加入删除链表
                    deleteList.AddLast(assetBundleName);
                }
            }

            //删除需要删除的
            Debug.Log("删除旧资源=>" + deleteList.ToJson());
            LinkedListNode<string> currDel = deleteList.First;
            while (currDel != null)
            {
                StringBuilder sbr = new StringBuilder();
                string filePath = sbr.AppendFormat("{0}/{1}", Application.persistentDataPath, currDel.Value).ToString();

                if (File.Exists(filePath)) File.Delete(filePath);
                LinkedListNode<string> next = currDel.Next;
                deleteList.Remove(currDel);
                currDel = next;
            }

            //检查需要下载的
            enumerator = VersionFile.m_CDNVersionDic.GetEnumerator();
            while (enumerator.MoveNext())
            {
                VersionFileEntity cdnAssetBundleInfo = enumerator.Current.Value;
                if (cdnAssetBundleInfo.IsFirstData)//检查初始资源
                {
                    if (!VersionFile.m_LocalAssetsVersionDic.ContainsKey(cdnAssetBundleInfo.AssetBundleName))
                    {
                        //如果可写区没有 加入下载链表
                        needDownloadList.AddLast(cdnAssetBundleInfo.AssetBundleName);
                    }
                }
            }

            CheckVersionBeginDownload?.Invoke();

            //进行下载
            Debug.Log("下载更新资源,文件数量==>" + needDownloadList.Count + "==>" + needDownloadList.ToJson());
            GameLaunch.DownloadAB.BeginDownloadMulit(needDownloadList, OnDownloadMulitUpdate, OnDownloadMulitComplete);
        }
        /// <summary>
        /// 下载进行中
        /// </summary>
        private void OnDownloadMulitUpdate(int t1, int t2, ulong t3, ulong t4)
        {
            m_DownloadingParams.IntParam1 = t1;
            m_DownloadingParams.IntParam2 = t2;

            m_DownloadingParams.ULongParam1 = t3;
            m_DownloadingParams.ULongParam2 = t4;

            CheckVersionDownloadUpdate?.Invoke(m_DownloadingParams);
        }
        /// <summary>
        /// 下载完毕
        /// </summary>
        private void OnDownloadMulitComplete()
        {
            VersionFile.SetVersionNumber(VersionFile.CDNVersionNumber);

            CheckVersionDownloadComplete?.Invoke();

            Debug.Log("检查更新下载完毕 进入预加载流程");
            CheckVersionComplete?.Invoke();
        }


        /// <summary>
        /// 单个文件检查更新(True==不需要更新)
        /// </summary>
        public bool CheckVersionChangeSingle(string assetBundleName)
        {
            if (VersionFile.m_CDNVersionDic.TryGetValue(assetBundleName, out VersionFileEntity cdnAssetBundleInfo))
            {
                if (VersionFile.m_LocalAssetsVersionDic.TryGetValue(cdnAssetBundleInfo.AssetBundleName, out VersionFileEntity LocalAssetsAssetBundleInfo))
                {
                    //可写区有 CDN也有 验证MD5
                    return cdnAssetBundleInfo.MD5.Equals(LocalAssetsAssetBundleInfo.MD5, StringComparison.CurrentCultureIgnoreCase);
                }
            }
            return false;//CDN不存在
        }

        public void Dispose()
        {
            VersionFile.Dispose();
        }
    }
}